package com.masasdani.paypal.service;

import com.masasdani.paypal.util.URLUtils;
import com.paypal.api.payments.*;
import com.paypal.api.payments.Currency;
import com.paypal.base.rest.APIContext;
import com.paypal.base.rest.PayPalRESTException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;

@Service
public class PayPalSubscriptionService {

    public static final String PAYPAL_SUCCESS_URL = "planOrderPaypal/success";
    public static final String PAYPAL_CANCEL_URL = "planOrderPaypal/cancel";

    @Autowired
    private APIContext apiContext;

    /**
     * 创建计划
     * @return
     * @throws PayPalRESTException
     */
    public Plan createPlan(HttpServletRequest request) throws PayPalRESTException {
        // 构建计划对象
        Plan plan = new Plan();
        plan.setName("Monthly Subscription Plan");
        plan.setDescription("Monthly subscription plan for premium services");
        //计费方案的类型。 允许的值：FIXED，INFINITE
        plan.setType("INFINITE");

        //付款参数
        PaymentDefinition paymentDefinition = new PaymentDefinition();
        paymentDefinition.setName("Monthly Payments");
        //付款定义的类型。 允许的值：“ TRIAL”，“ REGULAR”）。
        paymentDefinition.setType("REGULAR");
        //提供的付款定义的频率。 允许的值：“WEEK”，“DAY”，“YEAR”，“MONTH”。
        paymentDefinition.setFrequency("MONTH");
        //多久（setFrequency）向用户收取一次费用
        paymentDefinition.setFrequencyInterval("1");
        //收款的周期（次数）,无期限使用“0”
        paymentDefinition.setCycles("0");

        //金额
        Currency currency = new Currency();
        currency.setCurrency("USD");
        currency.setValue("3.0");
        paymentDefinition.setAmount(currency);

        List<PaymentDefinition> paymentDefinitions = new ArrayList<>();
        paymentDefinitions.add(paymentDefinition);

        //商家设置
        MerchantPreferences merchantPreferences = new MerchantPreferences();
        merchantPreferences.setSetupFee(new Currency().setCurrency("USD").setValue("3.0")); // 设置一次性启动费用为8.8美元
        String cancelUrl = URLUtils.getBaseURl(request) + "/" + PAYPAL_CANCEL_URL;
        String successUrl = URLUtils.getBaseURl(request) + "/" + PAYPAL_SUCCESS_URL;
        //支付成功后重定向到ReturnUrl地址
        merchantPreferences.setReturnUrl(successUrl);
        merchantPreferences.setCancelUrl(cancelUrl);
        //允许在下一个周期中为未结协议金额自动计费。 允许的值：“YES”，“NO”。 默认为“NO”。
        merchantPreferences.setAutoBillAmount("YES");
        //如果在首次付款期间发生故障，应采取的措施。 允许的值："CONTINUE"，"CANCEL"。 默认为"CONTINUE"。
        merchantPreferences.setInitialFailAmountAction("CONTINUE");
        //允许的失败尝试总数。默认值为0，表示无数次失败的尝试
        merchantPreferences.setMaxFailAttempts("0");

        plan.setPaymentDefinitions(paymentDefinitions);
        plan.setMerchantPreferences(merchantPreferences);

        Map<String, String> headers = new HashMap<>();
        headers.put("PayPal-Request-Id", generateRequestId());
        apiContext.setHTTPHeaders(headers);

        return plan.create(apiContext);
    }

    /**
     * 激活计划
     * @param planId
     * @throws PayPalRESTException
     */
    public void activatePlan(String planId) throws PayPalRESTException {
        Plan plan = Plan.get(apiContext, planId);
        List<Patch> patchRequestList = new ArrayList<>();
        Map<String, String> value = new HashMap<>();
        value.put("state", "ACTIVE");

        Patch patch = new Patch();
        patch.setOp("replace");
        patch.setPath("/");
        patch.setValue(value);
        patchRequestList.add(patch);

        Map<String, String> headers = new HashMap<>();
        headers.put("PayPal-Request-Id", generateRequestId());
        apiContext.setHTTPHeaders(headers);

        plan.update(apiContext, patchRequestList);
    }

    /**
     * 创建订单计划订阅
     * @param planId
     * @param date
     * @return
     */
    public String createPlanOrder(String planId, String date) {
        // 创建新的协议
        Agreement agreement = new Agreement();
        agreement.setName("Supernote会员-wenjie");
        agreement.setDescription("黄金会员，多重优惠特权");

        agreement.setStartDate(date);
        System.out.println("date = " + date);
        // 设置续费协议
        Plan plan = new Plan();
        plan.setId(planId);
        agreement.setPlan(plan);

        // 添加付款方式
        Payer payer = new Payer();
        payer.setPaymentMethod("paypal");
        agreement.setPayer(payer);

        // 添加收货地址
//        ShippingAddress shipping = new ShippingAddress();
//        shipping.setLine1("集心路168号-wenjie");
//        shipping.setCity("shanghai");
//        shipping.setState("上海市");
//        shipping.setPostalCode("200000");
//        shipping.setCountryCode("CN");
//        agreement.setShippingAddress(shipping);

        Map<String, String> headers = new HashMap<>();
        headers.put("PayPal-Request-Id", generateRequestId());
        apiContext.setHTTPHeaders(headers);
        // 创建协议
        try {
            agreement = agreement.create(apiContext);
//            System.out.println("agreementId = " + agreement);
            System.out.println("agreement.getToken = " + agreement.getToken());
            for (Links links : agreement.getLinks()) {
                if ("approval_url".equals(links.getRel())) {
                    URL url = new URL(links.getHref());
                    System.out.println("url = " + url);
                    return "redirect:" + links.getHref();
                }
            }
        } catch (PayPalRESTException e) {
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }

    public Agreement cancelledAgreement(String agreementId,double amountToRefund,String saleId) throws PayPalRESTException {
        // 获取支付详情
        Sale sale = Sale.get(apiContext, saleId);
        // 创建退款请求
        RefundRequest refundRequest = new RefundRequest();
        refundRequest.setAmount(new Amount("USD", amountToRefund+"")); // 请替换为实际的退款金额
        // 设置 PayPal-Request-Id 头部
        Map<String, String> headers = new HashMap<>();
        headers.put("PayPal-Request-Id", generateRequestId());
        apiContext.setHTTPHeaders(headers);
        // 执行退款
        DetailedRefund refund = sale.refund(apiContext, refundRequest);
        System.out.println("Refund ID: " + refund.getId());

        // 获取订阅协议
        Agreement agreement = Agreement.get(apiContext, agreementId);
        // 创建 AgreementStateDescriptor 对象，描述取消原因
        AgreementStateDescriptor agreementStateDescriptor = new AgreementStateDescriptor();
        agreementStateDescriptor.setNote("Cancelling the agreement due to user request after refund.");
        // 确保生成唯一的 PayPal-Request-Id
        apiContext.addHTTPHeader("PayPal-Request-Id", generateRequestId());
        apiContext.setRequestId(generateRequestId());
        // 取消订阅协议
        agreement.cancel(apiContext, agreementStateDescriptor);
        System.out.println("Subscription cancelled successfully.");

        return agreement;
    }

    public String execOrderplan(String token) {
        //用户支付成功后，重定向返回的页面携带的token
        Agreement agreement =  new Agreement();
        agreement.setToken(token);
        // 确保生成唯一的 PayPal-Request-Id
        apiContext.addHTTPHeader("PayPal-Request-Id", generateRequestId());
        apiContext.setRequestId(generateRequestId());
        try {
            Agreement activeAgreement = agreement.execute(apiContext, agreement.getToken());
//            System.out.println("Agreement is value:{} " + activeAgreement.toString());
            System.out.println("activeAgreement is value:{} " + activeAgreement.getId());
            return activeAgreement.getId();
        } catch (PayPalRESTException e) {
            System.err.println(e.getDetails());
        }
        return null;
    }

    private String generateRequestId() {
        return UUID.randomUUID().toString();
    }

}
